package com.meisupic.copyright.configuration;

import com.meisupic.copyright.support.security.CustomPasswordEncode;
import com.meisupic.copyright.support.security.HuaBanLoginAuthenticationProvider;
import com.meisupic.copyright.support.security.HuabanLoginFilter;
import com.meisupic.copyright.support.security.SSOFliter;
import com.meisupic.copyright.support.security.UserIdAuthenticationProvider;
import com.meisupic.copyright.support.security.UserIdLoginFilter;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


  @Autowired
  UserDetailsService userDetailsService;

  @Autowired
  UserDetailsService userCaidDetailsService;

  @Autowired
  UserDetailsService huabanLoginService;

  @Autowired
  AuthenticationSuccessHandler successHandler;

  @Autowired
  AuthenticationFailureHandler failureHandler;

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {

    AuthenticationManager authenticationManager = authenticationManager();
    UserIdLoginFilter userIdLoginFilter = new UserIdLoginFilter();
    userIdLoginFilter.setAuthenticationManager(authenticationManager);
    HuabanLoginFilter huabanLoginFilter = new HuabanLoginFilter();
    huabanLoginFilter.setAuthenticationManager(authenticationManager);
    SSOFliter ssoFliter = new SSOFliter();
    ssoFliter.setAuthenticationManager(authenticationManager);
    httpSecurity.headers().frameOptions().sameOrigin().and().csrf().disable()
        .authorizeRequests().antMatchers("/admin/**").hasAuthority("role_admin")
        .antMatchers("/copyright/**", "/vip-order", "/member/createOrder",
            "/member/getAccountAuthType").authenticated()
        .and().rememberMe().alwaysRemember(true).and()
        .formLogin().loginPage("/login").successHandler(successHandler)
        .failureHandler(failureHandler)
        .permitAll().and().addFilterBefore(userIdLoginFilter,
        UsernamePasswordAuthenticationFilter.class)
        .addFilterBefore(huabanLoginFilter, UsernamePasswordAuthenticationFilter.class)
        .addFilterBefore(ssoFliter, UserIdLoginFilter.class);

  }


  @Override
  public void configure(WebSecurity web) {
    web.ignoring().antMatchers("/static/**");

  }

  @Override
  protected AuthenticationManager authenticationManager() throws Exception {

    ReflectionSaltSource reflectionSaltSource = new ReflectionSaltSource();
    reflectionSaltSource.setUserPropertyToUse("salt");

    //将验证过程交给自定义验证工具
    DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    authenticationProvider.setPasswordEncoder(new CustomPasswordEncode());
    authenticationProvider.setUserDetailsService(userDetailsService);
    authenticationProvider.setSaltSource(reflectionSaltSource);

    UserIdAuthenticationProvider provider = new UserIdAuthenticationProvider();
    provider.setUserDetailsService(userCaidDetailsService);

    HuaBanLoginAuthenticationProvider huaBanLoginAuthenticationProvider = new HuaBanLoginAuthenticationProvider();
    huaBanLoginAuthenticationProvider.setUserDetailsService(huabanLoginService);

    ProviderManager authenticationManager = new ProviderManager(
        Arrays.asList(huaBanLoginAuthenticationProvider, provider, authenticationProvider));
    //不擦除认证密码，擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出UsernameNotFoundException
    authenticationManager.setEraseCredentialsAfterAuthentication(false);

    return authenticationManager;
  }

}
